use crate::worker::message::Message;
use crate::worker::handler::Handler;
use crate::worker::context::{WorkerContextImpl, WorkerContext};
use crate::worker::envelop::ToEnvelop;
use crate::channel::Sender;
use std::any::Any;
use std::collections::HashMap;

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Running {
    Stop,
    Continue,
}


pub trait Worker: Sized + 'static + Unpin {
    type Context: WorkerContext;

    /// 启动后使用的方法
    fn started(&mut self, _ctx: &mut Self::Context) {}

    /// 关闭时执行的函数
    fn stopping(&mut self, _ctx: &mut Self::Context) -> Running {
        Running::Stop
    }

    /// 关闭后执行的函数
    fn stopped(&mut self, _ctx: &mut Self::Context) {}

    /// 思考默认实现为什么外包
    /// 因为需要涉及具体的数据结构，采用组合解耦出去
    fn run(self, arg: Option<HashMap<String, Box<dyn Any>>>) -> WorkerSender<Self>
        where Self: Worker<Context=WorkerContextImpl<Self>>
    {
        WorkerContextImpl::new(arg).run(self)
    }
}

pub struct WorkerSender<A: Worker> {
    pub sender: Sender<A>
}

impl<A: Worker> WorkerSender<A> {
    pub fn send<M>(&self, msg: M)
        where M: Message + Send + 'static,
              A: Handler<M>,
              A::Context: ToEnvelop<A, M>
    {
        // let envelop = <A::Context as ToEnvelop<A, M>>::pack(msg);
        self.sender.send(msg);
    }
}

impl<A: Worker> Clone for WorkerSender<A> {
    fn clone(&self) -> Self {
        WorkerSender {
            sender: self.sender.clone(),
        }
    }
}





